tl;dr of http://docs.g-vo.org/DaCHS/tutorial.html
Uses example from http://svn.ari.uni-heidelberg.de/svn/gavo/hdinputs/arihip/q.rd
/var/gavo
/var/gavo/inputs
/var/gavo/etc
/var/gavo/logs
/var/gavo/web/
Root element <resource>
should define database schema, e.g. <resource schema="arihip">
One RD per schema
Example:
<meta name="title">ARIHIP astrometric catalogue</meta>
<meta name="creationDate">2010-11-03T10:13:00</meta>
<meta name="description">
The catalogue ARIHIP has been constructed by
selecting the 'best data' for a given star from combinations of HIPPARCOS
data with Boss' GC and/or the Tycho-2 catalogue as well as the FK6. It
provides 'best data' for 90 842 stars with a typical mean error of
0.89 mas/year (about a factor of 1.3 better than Hipparcos for this
sample of stars).
</meta>
<meta name="creator">Wielen, R.; Schwan, H.; Dettbarn, C.; et al</meta>
<meta name="subject">Catalogs</meta>
<meta name="subject">Astrometry</meta>
<meta name="subject">Stars: Proper Motions</meta>
<meta name="type">Catalog</meta>
<meta name="coverage.waveband">Optical</meta>
<coverage>
<spatial>0/0-11</spatial>
<spectral>2.721e-19 4.138e-19</spectral>
<temporal>1989-09-01 1993-08-15</temporal>
</coverage>
<FEED source="//procs#license-cc-by" what="ARIHIP"/>
<meta name="_longdoc" format="rst">
The ARIHIP Catalogue is a suitable combination of the results of the
HIPPARCOS astrometry satellite with ground-based data.
[...]
</meta>
<meta name="source">2001VeARI..40....1W</meta>
<meta name="_intro" format="rst"> <![CDATA[
For advanced queries on this catalogue use ADQL_
possibly via TAP_
.. _ADQL: /adql
.. _TAP: /tap
]]> </meta>
meta
is global metadata for RD_
indicates reserved for DaCHS internal usecoverage
metadata is inherited, e.g. if service in an RD has no title, it will use RD title
<table id="main" onDisk="True" adql="True" mixin="//scs#q3cindex" primary="hipno">
For every column in the table there will be a column element with attributes that are a mixture of VO-specific (e.g. unified content descriptors or ucd
) and SQL (e.g. name
or type
) e.g.
<column name="hipno" type="integer" ucd="meta.id;meta.main"
tablehead="HIP id" verbLevel="1"
description="Number of the star in the HIPPARCOS Catalogue (ESA 1997)."
required="True"/>
<column name="srcSel" type="text" ucd="meta.flag"
tablehead="Source" verbLevel="25"
description="Source of the astrometric solution"
note="src"/>
Can specify a child element of column
, values
. This allows one to set min/max, enumerate elements, specify null values... e.g.
<column name="n_obs" type="integer"
description="Number of
observations, NULL if interpolated data">
<values nullLiteral="-1"/>
</column>
Can also specify an index to be created for a table using a child element of table
, index
, e.g.
<index columns="mv"/>
<data id="import">
<sources>data/data.txt.gz</sources>
sources
child element defines path to source data
rawdict
(normally string -> string mapping)rowmaker
turns a rawdict
into rowdicts
, which is a mapping of rawdict column to a column that can be understood by the database <columnGrammar topIgnoredLines="9" preFilter="zcat">
<colDefs>
hipno: 3-8
srcSel: 47-49
alphaHMS: 59-73
[...]
</colDefs>
dachs imp -M 100 --dumpRows q.rd | less
topIgnoredLines
, preFilter
. The latter allows input to be preprocessed by a shell commandreGrammar
for delimiter or columnGrammer
for fixed-widthMake
element brings together a table with a recipe on how to fill it (row maker
)
Example:
<make table="main">
<rowmaker idmaps="*">
<var name="raj2000">hmsToDeg(@alphaHMS, None)</var>
<var name="dej2000">dmsToDeg(@deltaDMS, None)</var>
...
<map dest="kbin">parseWithNull(@kbin, str, "9")</map>
<map dest="vrad">parseWithNull(
@vrad, lambda a:float(killBlanks(a)), "")</map>
rowmaker
element has three kinds of childrenvar
: assignment of an expression value in the rawdict
map
: mapping of python expression to value in the destination rowdict
apply
: manipulation of rawdicts
and rowdicts
in python code@identifier
syntax expands to whatever the rawdict
has for the key identifier
In most cases map
will suffice if no other manipulation is required and a default conversion (e.g. python int
to sql integer
) is OK
Example:
<rowmaker>
<map dest="evi" src="evi"/>
<map dest="av" src="av"/>
<map dest="ai" src="ai"/>
</rowmaker>
or shorthand:
<rowmaker simplemaps="evi:evi,av:av,ai:ai"/>
or further shorthand where column names and identifiers have the same name:
<rowmaker idmaps="evi,av,ai"/>
or even shorter:
<rowmaker idmaps="*"/>
Service Definitions describe how to get data out of the database.
To understand this, need to understand basic DaCHS architecture:
Example:
<service id="cone" allowed="scs.xml,form">
<meta name="shortName">arihip cone</meta>
<meta name="testQuery">
<meta name="ra">9.4076</meta>
<meta name="dec">9.6414</meta>
<meta name="sr">1.0</meta>
</meta>
<dbCore queriedTable="main">
<FEED source="//scs#coreDescs"/>
<condDesc buildFrom="mv"/>
<condDesc>
<inputKey original="hipno" required="False"/>
</condDesc>
</dbCore>
<publish render="scs.xml" sets="ivo_managed"/>
<publish render="form" sets="ivo_managed,local"/>
<outputTable verbLevel="20"/>
</service>
allowed
attribute of service
shows the renderers available, i.e. xml
and form
dbCore
elements, i.e. here it is the in-built scsCore
. Other services include a generic
dbCore
, nullCore
(where no server-side computation is required), datalinkCore
as well as custom written coresdbCore
element generates a single table query against queriedTable
using condition descriptors condDesc
original
and buildFrom
are the most commonly used attributes of condDesc
:original
specifies a key that will be input by the user, e.g. by a formbuildFrom
builds an input definition from the column defined, e.g. mv
in this exampleThey can be declared at a RD level if shared by many services, in which case specify <dbCore core='id.of.element'>
regTest
child element of regSuite
. Basically consists test case with known result, e.g. <regSuite title="ARIHIP regression">
<regTest title="ARIHIP form service appears to work.">
<url parSet="form" hscs_sr="1.0" hscs_pos="0.00 1.08"
>cone/form</url>
<code>
self.assertHasStrings("PM RA (STP)",
"1.0890086361", "-5.00", "Note bin")
</code>
</regTest
inputs
directoryoriginal="main"
references the main
element in the current RD.
, e.g. myres/q#main.ra
references column ra
in the main
table in myres/q
//
references in-built RDs.//
) RDs...skipped for now.
Start DaCHS via docker (contains both postgres/dachs in one container):
eng@ubuntu:~$ docker run -it -p 8080:8080 --name dachs gavodachs/dachs
root@a27bb87ffb6e:/#service postgresql start
root@a27bb87ffb6e:/#dachs serve debug
Navigate to localhost at port 8080
Add data and set authority:
eng@ubuntu:~$ docker exec -it dachs /bin/bash
root@a27bb87ffb6e:/var/gavo/inputs# mkdir -p arihip/data
root@a27bb87ffb6e:/var/gavo/inputs# curl http://svn.ari.uni-heidelberg.de/svn/gavo/hdinputs/arihip/q.rd -o arihip/q.rd
root@a27bb87ffb6e:/var/gavo/inputs# curl http://dc.g-vo.org/arihip/q/cone/static/data.txt.gz -o arihip/data/data.txt.gz
root@a27bb87ffb6e:/var/gavo/inputs# gavo imp arihip/q && gavo pub arihip/q
root@a27bb87ffb6e:/var/gavo/inputs# vim /etc/gavo.rc
[web]
sitename: Dachs-on-Docker
bindAddress:
serverPort: 8080
serverURL: http://localhost:8080
logFormat: combined
[ivoa]
authority: test.rmb
Reset the DaCHS server:
root@a27bb87ffb6e:/# ^C
root@a27bb87ffb6e:/#dachs serve debug
Import the RD and publish:
root@a27bb87ffb6e:/var/gavo/inputs# gavo imp arihip/q && gavo pub arihip/q
Reset the DaCHS server:
root@a27bb87ffb6e:/# ^C
root@a27bb87ffb6e:/#dachs serve debug
Navigate to localhost at port 8080 again
Use some target in SCS e.g. HD 27846
obscore
table is a view
, mapping resources from other individual tables on to this schemamixin
from the //obscore
RD with filled out parameters that are used to
construct the required SQL data defininition language (DDL) statements that comprise the viewSIAP
(simple image access protocl), it is possible to use something like mixin="//obscore#publishSIAP"
to add existing data<mixin sResolution="0.5" calibLevel="2">//obscore#publishSIAP</mixin>
obs_publisher_did
column, often used as primary key (i.e. unique)...skipped for now.
...skipped for now.
...skipped for now.
adql=True
to table definition, add <publish/>
to table body and update metadata dachs imp -m
<publish sets="ivo_managed, local"/>
Discouraged, but necessary if data lives in another table. Example:
<resource schema="mydata">
<meta name="title">My great table</meta>
<meta name="creationDate">... (more metadata)
<table id="values" onDisk="True" adql="True">
<column name="id" type="bigint" unit="" ucd="meta.id;meta.main">
<description>id of object covered here</description></column>
</table>
<data id="d" updating="True">
<publish/>
<make table="values"/>
</data>
</resource>
<data>
element has no sources
updating
makes sure that DaCHS doesn't tear down the table-m
flag during DaCHS import to import only metadataDaCHS must be able to modify these tables, so ensure that privileges are granted to gavoadmin
in the database